package com.quanyan.place.service.impl;

import com.quanyan.api.APIRequest;
import com.quanyan.api.APIResponse;
import com.quanyan.common.Plugin.Page;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.common.utils.TimeUtils;

import com.quanyan.orderpay.request.ReqOrderSave;
import com.quanyan.orderpay.request.ReqPayInfo;
import com.quanyan.orderpay.request.ReqProductDetail;
import com.quanyan.orderpay.response.RespPreOrder;
import com.quanyan.orderpay.response.mq.OrderNotifyMsg;
import com.quanyan.orderpay.response.mq.WithdrawTransferNotify;
import com.quanyan.orderpay.service.OrderPayService;
import com.quanyan.pay.enums.PayWayEnum;
import com.quanyan.place.constants.PlaceConstants;
import com.quanyan.place.entity.*;
import com.quanyan.place.entity.apireq.*;
import com.quanyan.place.entity.apiresp.*;
import com.quanyan.place.mapper.*;
import com.quanyan.place.service.AdminUserService;
import com.quanyan.place.service.PlaceBaseService;
import com.quanyan.place.service.PlaceBizSettleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;

/**
 * Created by yuanxuebing on 16-10-21.
 */
@Service
public class PlaceBizSettleServiceImpl implements PlaceBizSettleService {

    private static final Logger logger = LoggerFactory.getLogger(PlaceBizSettleServiceImpl.class);

    @Autowired
    private TbBizPlaceOrderMapper placeOrderMapper;

    @Autowired
    private TbBizPlaceMemberOpHistoryMapper opHistoryMapper;

    @Autowired
    private TbBizPlaceStatementMapper statementsMapper;

    @Autowired
    private TbBizPlaceStatementDetailMapper statementDetailMapper;

    @Autowired
    private StatementRunningNumMapper runningNumMapper;

    @Autowired
    private PlaceCashUnSettleOrderMapper unSettleOrderMapper;


    @Autowired
    private PlaceBaseService placeBaseService;

    @Autowired
    OrderPayService orderPayService;

    @Autowired
    AdminUserService adminUserService;



    @Value("${notify.url.cashForScanTransfer}")
    private String cashForScanTransfer;

    StatementBaseInfo constructBaseInfo(TbBizPlaceStatement statement) {
        if (statement == null) {
            return null;
        }

        StatementBaseInfo baseInfo = new StatementBaseInfo();

        baseInfo.setId(statement.getId());
        baseInfo.setStatementId(statement.getStatementId());
        baseInfo.setPlaceId(statement.getPlaceId());
        baseInfo.setTotalAmount(statement.getTotalAmount());
        baseInfo.setCreateName(statement.getCreateName());
        baseInfo.setCreateDate(statement.getCreateDate());
        baseInfo.setUid(statement.getTansferUid());
        if (baseInfo.getUid()!=null){
            TbAdminUser user=adminUserService.getAdminUser(baseInfo.getUid());
            baseInfo.setTransferName(user.getTrueName());
        }
        baseInfo.setTransferDate(statement.getTransferDate());
        baseInfo.setStatementStatus(statement.getStatementStatus());
        baseInfo.setSettleName(statement.getSettleName());
        baseInfo.setSettleDate(statement.getSettleDate());
        baseInfo.setBankAccount(statement.getBankAccount());
        baseInfo.setTransferRemark(statement.getTransferRemark());
        baseInfo.setSettleRemark(statement.getSettleRemark());
        baseInfo.setWeixinCodeUrl(statement.getWeixinCodeUrl());
        baseInfo.setAliPayCodeUrl(statement.getAliPayCodeUrl());

        return baseInfo;
    }

    SettleOrder newSettleOrderFromTbPlaceOrder(TbBizPlaceOrder tovo, int flag) {
        SettleOrder ovo = new SettleOrder();

        ovo.setOrderId(tovo.getId());
        ovo.setOrderNo(tovo.getPlaceOrderId());
        ovo.setOrderType((byte) 1);  //普通订单
        ovo.setOrderStatus(tovo.getOrderStatus());

        // 由订单状态决定
        if (flag == 0) {
            if (tovo.getOrderStatus() == 5) {
                flag = 2;
            } else {
                flag = 1;
            }
        }

        // 算收入
        if (flag == 1)
        {
            ovo.setPayAmount(tovo.getDebit());
            int i = tovo.getDebit().compareTo(BigDecimal.ZERO);
            if (i == 1) {
                ovo.setPayAmount(tovo.getDebit());
            } else if (i == 0 || i == -1) {  // 注意退款会把debit置零
                int j = tovo.getCredit().compareTo(BigDecimal.ZERO);
                if (j == 1) {
                    ovo.setPayAmount(tovo.getCredit());
                }
            }
            ovo.setPaymentTime(tovo.getPaymentTime());
        }
        // 算支出
        else if (flag == 2){
            BigDecimal munusCredit = tovo.getCredit().multiply(new BigDecimal(-1));
            ovo.setPayAmount(munusCredit);
            ovo.setPaymentTime(tovo.getRefundTime());
        }

        ovo.setDebit(tovo.getDebit());
        ovo.setCredit(tovo.getCredit());
       /* ovo.setCashStatus(tovo.getCashStatus());
        ovo.setRefundCashStatus(tovo.getRefundCashStatus());*/

        return ovo;
    }

    SettleOrder newSettleOrderFromTbMemberOpHistory(TbBizPlaceMemberOpHistory tovo) {
        SettleOrder ovo = new SettleOrder();

        ovo.setOrderId(tovo.getId());
        ovo.setOrderNo(tovo.getOrderNo());
        ovo.setOrderType((byte) 2);  //　充值订单
        //ovo.setOrderStatus((byte) 6); // 充值已经完成
        ovo.setPayAmount(tovo.getAmount());
        ovo.setPaymentTime(tovo.getCreateTime());
        /*ovo.setCashStatus(tovo.getCashStatus());*/

        // 新增字段
        ovo.setDebit(tovo.getAmount());
        ovo.setCredit(BigDecimal.ZERO);

        return ovo;
    }

    // 批量查询普通订单
    List<SettleOrder> batchNormalOrders(Integer placeId, List<Integer> ids) {
        List<SettleOrder> settleOrderList = new ArrayList<SettleOrder>();

        if (ids == null || ids.size() <= 0) {
            return settleOrderList;
        }

        TbBizPlaceOrderExample rExample = new TbBizPlaceOrderExample();
        TbBizPlaceOrderExample.Criteria rCriteria = rExample.createCriteria();
        rCriteria.andPlaceIdEqualTo(placeId);
        rCriteria.andIdIn(ids);

        List<TbBizPlaceOrder> tbOrderList = placeOrderMapper.selectByExample(rExample);
        for (TbBizPlaceOrder tovo : tbOrderList) {
            SettleOrder ovo = this.newSettleOrderFromTbPlaceOrder(tovo, 0);
            settleOrderList.add(ovo);
        }

        return settleOrderList;
    }

    // 批量查询会员订单
    List<SettleOrder> batchMemberOrders(Integer placeId, List<Integer> ids) {
        List<SettleOrder> settleOrderList = new ArrayList<SettleOrder>();

        if (ids == null || ids.size() <=0) {
            return settleOrderList;
        }

        TbBizPlaceMemberOpHistoryExample rExample = new TbBizPlaceMemberOpHistoryExample();
        TbBizPlaceMemberOpHistoryExample.Criteria rCriteria = rExample.createCriteria();
        rCriteria.andPlaceIdEqualTo(placeId);
        rCriteria.andIdIn(ids);

        List<TbBizPlaceMemberOpHistory> tbBizPlaceMemberOpHistoryList = opHistoryMapper.selectByExample(rExample);
        for (TbBizPlaceMemberOpHistory tovo : tbBizPlaceMemberOpHistoryList) {
            SettleOrder ovo = this.newSettleOrderFromTbMemberOpHistory(tovo);
            settleOrderList.add(ovo);
        }

        return settleOrderList;
    }

    // 获取未结算的普通订单
    List<SettleOrder> listUnSettleNormalOrders(Integer placeId, Date startDate, Date endDate) {
        // 所有收入的订单
        List<Byte> validStatus = new ArrayList<Byte>();
        validStatus.add((byte) 3);
        validStatus.add((byte) 4);
        validStatus.add((byte) 5);
        validStatus.add((byte) 6);

        TbBizPlaceOrderExample rExample = new TbBizPlaceOrderExample();
        TbBizPlaceOrderExample.Criteria rCriteria = rExample.createCriteria();
        rCriteria.andPlaceIdEqualTo(placeId);
        rCriteria.andOrderStatusIn(validStatus);
      /*  rCriteria.andCashStatusEqualTo((byte) 1);  // 收入结算状态为未申请的订单*/
        rCriteria.andPaymentTimeBetween(startDate, endDate);
        rCriteria.andSourceTypeEqualTo((byte) 2);  // 只考虑现金支付的

        List<TbBizPlaceOrder> tbOrderList = placeOrderMapper.selectByExample(rExample);
        List<SettleOrder> settleOrderList = new ArrayList<SettleOrder>();
        for (TbBizPlaceOrder tovo : tbOrderList) {
            SettleOrder ovo = this.newSettleOrderFromTbPlaceOrder(tovo, 1);
            settleOrderList.add(ovo);
        }

        // 所有支出的订单
        TbBizPlaceOrderExample rExample2 = new TbBizPlaceOrderExample();
        TbBizPlaceOrderExample.Criteria rCriteria2 = rExample2.createCriteria();
        rCriteria2.andPlaceIdEqualTo(placeId);
        rCriteria2.andOrderStatusEqualTo((byte) 5);         // 订单类型是已退款的
       /* rCriteria2.andRefundCashStatusEqualTo((byte) 1);    // 支出结算状态为未申请的订单*/
        rCriteria2.andRefundTimeBetween(startDate, endDate);
        rCriteria2.andSourceTypeEqualTo((byte) 2);          // 现场现金支付

        List<TbBizPlaceOrder> tbOrderList2 = placeOrderMapper.selectByExample(rExample2);
        for (TbBizPlaceOrder tovo : tbOrderList2) {
            SettleOrder ovo = this.newSettleOrderFromTbPlaceOrder(tovo, 2);
            settleOrderList.add(ovo);
        }

        return settleOrderList;
    }

    // 获取未结算的会员订单
    List<SettleOrder> listUnSettleMemberOrders(Integer placeId, Date startDate, Date endDate) {
        TbBizPlaceMemberOpHistoryExample rExample = new TbBizPlaceMemberOpHistoryExample();
        TbBizPlaceMemberOpHistoryExample.Criteria rCriteria = rExample.createCriteria();
        rCriteria.andPlaceIdEqualTo(placeId);
        rCriteria.andAdminPayTypeEqualTo(20);
        rCriteria.andSrcEqualTo(5);
        rCriteria.andStateEqualTo((byte)1);
        rCriteria.andCreateTimeBetween(startDate, endDate);

        List<TbBizPlaceMemberOpHistory> tbBizPlaceMemberOpHistoryList = opHistoryMapper.selectByExample(rExample);
        List<SettleOrder> settleOrderList = new ArrayList<SettleOrder>();
        for (TbBizPlaceMemberOpHistory tovo : tbBizPlaceMemberOpHistoryList) {
            SettleOrder ovo = this.newSettleOrderFromTbMemberOpHistory(tovo);
            settleOrderList.add(ovo);
        }

        return settleOrderList;
    }

    // 更新普通账单结算状态(refund:是否是退款订单)
    int updateNormalOrderSettleStatus(List<Integer> ids, List<String> orderNOs, byte newStatus, boolean refund) {
        if ((ids == null || ids.size() <= 0) && (orderNOs == null || orderNOs.size() <= 0)) {
            return -1;
        }

        TbBizPlaceOrder voOrder = new TbBizPlaceOrder();
        if (refund) {
          /*  voOrder.setRefundCashStatus(newStatus); // 退款的就更新退款结算状态*/
        } else {
           /* voOrder.setCashStatus(newStatus);*/
        }

        TbBizPlaceOrderExample poExample = new TbBizPlaceOrderExample();
        TbBizPlaceOrderExample.Criteria poCriteria = poExample.createCriteria();

        if (ids != null && ids.size() > 0) {
            poCriteria.andIdIn(ids);

        }

        if (orderNOs != null && orderNOs.size() > 0) {
            poCriteria.andPlaceOrderIdIn(orderNOs);
        }

        return placeOrderMapper.updateByExampleSelective(voOrder, poExample);
    }

    // 更新会员订单结算状态
    int updateMemberOrderSettleStatus(List<Integer> ids, List<String> orderNOs, byte newStatus) {
        if ((ids == null || ids.size() <= 0) && (orderNOs == null || orderNOs.size() <= 0)) {
            return -1;
        }

        TbBizPlaceMemberOpHistory opHistory = new TbBizPlaceMemberOpHistory();
      /*  opHistory.setCashStatus(newStatus);*/

        TbBizPlaceMemberOpHistoryExample ophExample = new TbBizPlaceMemberOpHistoryExample();
        TbBizPlaceMemberOpHistoryExample.Criteria ophCriteria = ophExample.createCriteria();

        if (ids != null && ids.size() > 0) {
            ophCriteria.andIdIn(ids);
        }

        if (orderNOs != null && orderNOs.size() > 0) {
            ophCriteria.andOrderNoIn(orderNOs);
        }

        return opHistoryMapper.updateByExampleSelective(opHistory, ophExample);
    }

    static public String createMapKey(Byte orderType, Integer id) {
        return String.format("%d_%d", orderType, id);
    }

    @Override
    public List<SettleOrder> listUnSettleOrders(ReqListUnSettleOrders reqVo) {
        Integer placeId = reqVo.getPlaceId();
        Date startDate = reqVo.getPayStartDate();
        Date tmp = reqVo.getPayEndDate();
        Date endDate = TimeUtils.getDateAfterSeconds(tmp, (24*60*60 - 1));
        reqVo.setPayEndDate(endDate);

        List<SettleOrder> allOrders = new ArrayList<>();
        //List<SettleOrder> normalOrders = this.listUnSettleNormalOrders(placeId, startDate, endDate);    // 普通订单
        List<SettleOrder> normalOrders = unSettleOrderMapper.listUnSettleNormalOrders(reqVo);
        List<SettleOrder> memberOrders = this.listUnSettleMemberOrders(placeId, startDate, endDate);    // 会员充值订单
        allOrders.addAll(normalOrders);
        allOrders.addAll(memberOrders);
        logger.info("req:[{}] result:[{}/{}/{}]", reqVo, allOrders.size(), normalOrders.size(), memberOrders.size());

        return allOrders;
    }

    public List<SettleOrder> getStatementDetailByDate(Integer placeId,String orderNo,Integer orderType,Date date){
        ReqListUnSettleOrders orderVo = new ReqListUnSettleOrders();
        orderVo.setPlaceId(placeId);
        //orderVo.setOrderNo(orderNo);
        orderVo.setOrderType(orderType);
        orderVo.setCreateDate(date);
        List<SettleOrder> list=unSettleOrderMapper.getStatementDetailByDate(orderVo);
        return list;
    }

    /**
     * 自营场馆现金结算，消费订单，会员卡充值订单
     * @param
     */
     @Override
    public void createStatement() {
     /*   List<Integer> debitIds = new ArrayList<Integer>();   // 收入单集合
        List<Integer> creditIds = new ArrayList<Integer>();  // 支出单集合
        List<Integer> memberIds = new ArrayList<Integer>();*/
         ReqCreateStatement reqVo=new ReqCreateStatement();
        //获取自营场馆
        List<TbBizPlace> placeList = placeBaseService.getPoolPlace((byte) 1, 0, 1);
        //根据每个场馆ID 看下昨天的支付订单，按照付款时间，然后打包 打包成一个
        for (TbBizPlace place : placeList) {
            if (place.getId() == null) {
                continue;
        }
            if (place.getId().intValue()==38079){
                logger.info("Asasasas");
            }
            List<SettleOrder> unSettleConsumeOrderList = new ArrayList<>();
            List<SettleOrder> unSettleMemberOrdersList = new ArrayList<>();
            //获得已结算最后消费的订单的付款时间
            SettleOrder unsetterOrderVo = unSettleOrderMapper.getMaxCashConsumeOrder(place.getId());
            if (unsetterOrderVo != null) {
                ReqListUnSettleOrders orderVo = new ReqListUnSettleOrders();
                orderVo.setPlaceId(place.getId());
                //结算上一次付款日期，跟当前时间前一天的区间
                Date dateStart=DateUtils.addNDay(unsetterOrderVo.getPaymentTime(),1);
                orderVo.setPayStartDate(DateUtils.getDateFormat(dateStart));
                orderVo.setPayEndDate(DateUtils.getDateFormat(new Date()));
                Boolean isfor = DateUtils.dateTimeCompare(orderVo.getPayStartDate(), orderVo.getPayEndDate(), true);
                //如果付款时间大于或等于当前时间
                if (!isfor) {
                    //获得消费订单
                    unSettleConsumeOrderList = unSettleOrderMapper.listUnSettleNormalOrders(orderVo);
                    //检查结算过的订单号跟将要结算的订单号有没重复的，避免重复结算
                    if (unSettleConsumeOrderList!=null&&unSettleConsumeOrderList.size()>0){
                        Date date=null;
                        try {
                            date=DateUtils.reduceDay(new Date(),2);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        //SettleOrder cVo=unSettleConsumeOrderList.get(0);
                        //查看要打包结算订单号与前一天地订单号有没重复，有的话移除，不参与打包结算
                        List<SettleOrder> sList=this.getStatementDetailByDate(place.getId(),null,1,date);
                        List<SettleOrder>  delConsumeList=new ArrayList<>();
                        for (int i=0;i<unSettleConsumeOrderList.size();i++){
                                for(int j=0;j<sList.size();j++){
                                    SettleOrder so=unSettleConsumeOrderList.get(i);
                                    SettleOrder lo=sList.get(j);
                                    if (so.getOrderNo().equals(lo.getOrderNo())){
                                        delConsumeList.add(so);
                                    }
                                }
                        }
                        //移除有重复的订单号
                        if (delConsumeList!=null&&delConsumeList.size()>0){
                            for (SettleOrder dc:delConsumeList){
                                unSettleConsumeOrderList.remove(dc);
                            }
                        }

                       /* if (sList!=null&&sList.size()>0){
                            unSettleConsumeOrderList=null;
                        }*/


                    }
                }else{
                    continue;
                }
            }else{
                ReqListUnSettleOrders orderVo = new ReqListUnSettleOrders();
                orderVo.setPlaceId(place.getId());
                //结算上一次付款日期，跟当前时间前一天的区间
                orderVo.setPayStartDate(DateUtils.getDateFormat(DateUtils.getYestodayToDate(new Date())));
                orderVo.setPayEndDate(DateUtils.getDateFormat(new Date()));
                unSettleConsumeOrderList = unSettleOrderMapper.listUnSettleNormalOrders(orderVo);
            }
            //获得已结算最后充值会员卡的付款时间
            SettleOrder unsetterMemberVo = unSettleOrderMapper.getMaxCashMemberOrder(place.getId());
            if (unsetterMemberVo != null) {
                ReqListUnSettleOrders memVo = new ReqListUnSettleOrders();
                memVo.setPlaceId(place.getId());
                //结算上一次付款日期，跟当前时间前一天的区间
                Date dateStart=DateUtils.addNDay(unsetterMemberVo.getPaymentTime(),1);
                memVo.setPayStartDate(DateUtils.getDateFormat(dateStart));
                memVo.setPayEndDate(DateUtils.getDateFormat(new Date()));
                Boolean isfor = DateUtils.dateTimeCompare(memVo.getPayStartDate(), memVo.getPayEndDate(), true);
                //如果付款时间大于或等于当前时间
                if (!isfor) {
                    //获得充值订单
                    unSettleMemberOrdersList = this.listUnSettleMemberOrders(place.getId(), memVo.getPayStartDate(), memVo.getPayEndDate());
                    //检查结算过的订单号跟将要结算的订单号有没重复的，避免重复结算
                    if (unSettleMemberOrdersList!=null&&unSettleMemberOrdersList.size()>0){
                        Date date=null;
                        try {
                            date=DateUtils.reduceDay(new Date(),2);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        //SettleOrder unVo=unSettleMemberOrdersList.get(0);
                        //查看要打包结算订单号与前一天地订单号有没重复，有的话移除，不参与打包结算
                        List<SettleOrder> mList=this.getStatementDetailByDate(place.getId(),null,2,date);
                        List<SettleOrder>  delMemberList=new ArrayList<>();
                        for (int i=0;i<unSettleMemberOrdersList.size();i++){
                            for(int j=0;j<mList.size();j++){
                                SettleOrder so=unSettleMemberOrdersList.get(i);
                                SettleOrder lo=mList.get(j);
                                if (so.getOrderNo().equals(lo.getOrderNo())){
                                    delMemberList.add(so);
                                }
                            }
                        }
                        //移除有重复的订单号
                        if (delMemberList!=null&&delMemberList.size()>0){
                            for (SettleOrder dm:delMemberList){
                                unSettleMemberOrdersList.remove(dm);
                            }
                        }
                       /* if (mList!=null&&mList.size()>0){
                            unSettleMemberOrdersList=null;
                        }*/
                    }
                }else {
                    continue;
                }
            }else{
                ReqListUnSettleOrders memVo = new ReqListUnSettleOrders();
                memVo.setPlaceId(place.getId());
                //结算上一次付款日期，跟当前时间前一天的区间
                memVo.setPayStartDate(DateUtils.getDateFormat(DateUtils.getYestodayToDate(new Date())));
                memVo.setPayEndDate(DateUtils.getDateFormat(new Date()));
                unSettleMemberOrdersList = this.listUnSettleMemberOrders(place.getId(), memVo.getPayStartDate(), memVo.getPayEndDate());
            }

            //充值订单，消费订单金额累加，打包
            if ((unSettleConsumeOrderList != null && unSettleConsumeOrderList.size() > 0) || (unSettleMemberOrdersList != null && unSettleMemberOrdersList.size() > 0)) {
                BigDecimal payAmount = new BigDecimal(0);
                if (unSettleConsumeOrderList != null && unSettleConsumeOrderList.size() > 0){
                    for (SettleOrder unOrder:unSettleConsumeOrderList) {
                        payAmount=payAmount.add(unOrder.getPayAmount());
                    }
                }
                if (unSettleMemberOrdersList != null && unSettleMemberOrdersList.size() > 0) {
                    for (SettleOrder unMem : unSettleMemberOrdersList) {
                        payAmount=payAmount.add(unMem.getPayAmount());
                    }
                }
                TbBizPlaceStatement tbStatement = new TbBizPlaceStatement();

                // 系统生成结算单号:一共12位，XJ（前辍）+ 161017（年月日）+ 0001（自增流水号），如：XJ1610170001
                if (reqVo.getCreateDate() == null) {
                    reqVo.setCreateDate(DateUtils.getYestodayToDate(new Date()));
                }

                java.text.DateFormat format = new java.text.SimpleDateFormat("yyyyMMdd");
                String createDateStr = format.format(reqVo.getCreateDate());

                String runingKey = String.format("XJ%s", createDateStr);
                int num = 0;
                synchronized (this) {

                    int count = runningNumMapper.getRunningNumCount(runingKey);
                    if (count > 0) {
                        num = runningNumMapper.getRunningNum(runingKey);
                        num = num + 1;
                        runningNumMapper.updateRuningNum(runingKey, num);
                        //suffix=runningNumMapper.getRunningNum(RNKey);
                    } else {
                        runningNumMapper.saveNewRuningNum(runingKey);
                        num = runningNumMapper.getRunningNum(runingKey);
                    }

                    String statementNo = String.format("XJ%s%05d", createDateStr, num);
                    tbStatement.setStatementId(statementNo);
                    tbStatement.setPlaceId(place.getId());
                    tbStatement.setTotalAmount(payAmount);
                    //tbStatement.setCreateName(reqVo.getCreateName());
                    tbStatement.setCreateDate(reqVo.getCreateDate());
                    tbStatement.setStatementStatus((byte) 1); // 设置结算单为申请结算

                    ReqTransferStatement reqTransferVo=new ReqTransferStatement();
                    //提交到支付系统,因为要获取微信扫码二维码链接与支付宝扫码二维码链接，所以要请求两次到订单系统（微信支付方式，支付宝支付方式）
                    reqTransferVo.setStatementId(statementNo);
                    reqTransferVo.setTransferAmount(payAmount);
                   /* APIResponse<RespPreOrder> respWeixin=this.cashForScanTransfer(reqTransferVo,unSettleConsumeOrderList,unSettleMemberOrdersList,PayWayEnum.PAY_WAY_WEICHAT_SCAN_CODE.getPayId());
                    APIResponse<RespPreOrder> respAli=this.cashForScanTransfer(reqTransferVo,unSettleConsumeOrderList,unSettleMemberOrdersList,PayWayEnum.PAY_WAY_ALIPAY_SCAN_CODE.getPayId());
                    tbStatement.setWeixinErrMsg(respWeixin!=null&&respWeixin.isRet()==false?respWeixin.getErrmsg():null);
                    tbStatement.setAliErrMsg(respAli!=null&&respAli.isRet()==false?respAli.getErrmsg():null);
                   if (respWeixin!=null){
                       tbStatement.setWeixinCodeUrl(respWeixin.getData()!=null?respWeixin.getData().getCodeUrl():null);
                   }
                    if (respAli!=null){
                        tbStatement.setAliPayCodeUrl(respAli.getData()!=null?respAli.getData().getCodeUrl():null);
                    }
                    if (respWeixin!=null){
                        tbStatement.setPayOrderNo(respWeixin.getData()!=null?respWeixin.getData().getOrderNo():null);
                    }*/
                    // 保存结算单基本信息
                        int ret = statementsMapper.insertSelective(tbStatement);
                        if (ret < 1) {
                            continue;
                        }
                    int id = tbStatement.getId()!=null?tbStatement.getId():0;
                    // 添加消费订单结算详情
                    if ((unSettleConsumeOrderList != null && unSettleConsumeOrderList.size() > 0)) {
                        for (SettleOrder order : unSettleConsumeOrderList) {
                            Byte orderType = order.getOrderType();
                            TbBizPlaceStatementDetail detail = new TbBizPlaceStatementDetail();
                            detail.setStatementId(id);
                            detail.setPlaceOrderId(order.getOrderNo());
                            detail.setOrderType(orderType);
                            // 把金额和支付时间一起存入数据表中
                            detail.setHandleMoney(order.getPayAmount());
                            detail.setPayTime(order.getPaymentTime());
                            // 这里可以考虑保存一下订单是 收入 还是 支出 的标志,暂时通过金额来判断
                            statementDetailMapper.insertSelective(detail);
                        }
                    }
                    // 添加充值订单结算详情
                    if ((unSettleMemberOrdersList != null && unSettleMemberOrdersList.size() > 0)){
                        for (SettleOrder order : unSettleMemberOrdersList) {
                            Byte orderType = order.getOrderType();
                            TbBizPlaceStatementDetail detail = new TbBizPlaceStatementDetail();
                            detail.setStatementId(id);
                            detail.setPlaceOrderId(order.getOrderNo());
                            detail.setOrderType(orderType);
                            // 把金额和支付时间一起存入数据表中
                            detail.setHandleMoney(order.getPayAmount());
                            detail.setPayTime(order.getPaymentTime());
                            // 这里可以考虑保存一下订单是 收入 还是 支出 的标志,暂时通过金额来判断
                            statementDetailMapper.insertSelective(detail);
                        }
                    }
                }
            }
        }
    }

    @Override
    public PageObj<List<StatementBaseInfo>> listPlaceStatements(ReqListPlaceStatements reqVo) {
        Integer pageNum = 0;
        Integer pageSize = 30;   // 默认每页30

        if (reqVo != null) {
            if (reqVo.getPageNum() != null) {
                pageNum = reqVo.getPageNum();
            }
            if (reqVo.getPageSize() != null) {
                pageSize = reqVo.getPageSize();
            }
        }

        List<StatementBaseInfo> baseInfos = new ArrayList<StatementBaseInfo>();

        TbBizPlaceStatementExample rExample = new TbBizPlaceStatementExample();
        TbBizPlaceStatementExample.Criteria rCriteria = rExample.createCriteria();
        rCriteria.andPlaceIdEqualTo(reqVo.getPlaceId());
        if (reqVo.getStatementStatus() > 0) {
            rCriteria.andStatementStatusEqualTo(reqVo.getStatementStatus());
        }

        if (reqVo.getCreateStartDate() != null) {
            rCriteria.andCreateDateGreaterThanOrEqualTo(reqVo.getCreateStartDate());
        }
        if (reqVo.getCreateEndDate() != null) {
            rCriteria.andCreateDateLessThanOrEqualTo(reqVo.getCreateEndDate());
        }

        if (reqVo.getSettleStartDate() != null) {
            rCriteria.andSettleDateGreaterThanOrEqualTo(reqVo.getSettleStartDate());
        }
        if (reqVo.getSettleEndDate() != null) {
            rCriteria.andSettleDateLessThanOrEqualTo(reqVo.getSettleEndDate());
        }
        if (!StringUtils.isEmpty(reqVo.getStatementId())){
            rCriteria.andStatementIdLike("%"+reqVo.getStatementId()+"%");
        }else{
            reqVo.setStatementId(null);
        }

        // 先获取总数
        int totalNum = statementsMapper.countByExample(rExample);

        // 分页
        rExample.setOrderByClause("id DESC");
        Page page = new Page(pageNum * pageSize, pageSize, totalNum);
        rExample.setPage(page);

        List<TbBizPlaceStatement> statements = statementsMapper.selectByExample(rExample);
        if (statements != null) {
            for (TbBizPlaceStatement statement : statements) {
                baseInfos.add(this.constructBaseInfo(statement));
            }
        }

        PageObj<List<StatementBaseInfo>> result = PageObj.create(totalNum, pageNum, pageSize, baseInfos);

        return result;
    }

    @Override
    public StatementInfo getStatementInfo(ReqGetStatementInfo reqVo) {
        TbBizPlaceStatement statement = statementsMapper.selectByPrimaryKey(reqVo.getId());
        if (statement == null) {
            return null;
        }
        //保存转账人，如果对账单已经结算则不更新转账人，
        if (statement!=null){
            if (statement.getStatementStatus()!=null){
                if (statement.getStatementStatus().intValue()==1){
                    TbBizPlaceStatement vo=new TbBizPlaceStatement();
                    vo.setId(reqVo.getId());
                    vo.setTansferUid(reqVo.getUid());
                    statementsMapper.updateByPrimaryKeySelective(vo);
                }
            }
        }

        // 获取结算单明细
        List<SettleOrder> orders = new ArrayList<SettleOrder>();
        TbBizPlaceStatementDetailExample sdExample = new TbBizPlaceStatementDetailExample();
        TbBizPlaceStatementDetailExample.Criteria sdCriteria = sdExample.createCriteria();
        sdCriteria.andStatementIdEqualTo(reqVo.getId());

        List<TbBizPlaceStatementDetail> details = statementDetailMapper.selectByExample(sdExample);
        if (details != null) {
            for (TbBizPlaceStatementDetail detail : details) {
                SettleOrder order = new SettleOrder();
                order.setOrderNo(detail.getPlaceOrderId());
                order.setOrderType(detail.getOrderType());
                order.setPayAmount(detail.getHandleMoney());
                order.setPaymentTime(detail.getPayTime());
                orders.add(order);
            }
        }
        //点击明细 将总金额，对账单号传递给支付系统，返回微信支付宝二维码链接
        TbBizPlaceStatement  tbStatement=new TbBizPlaceStatement();
        tbStatement.setId(reqVo.getId());
        APIResponse<RespPreOrder> respWeixin=this.cashForScanTransfer(statement,details,PayWayEnum.PAY_WAY_WEICHAT_SCAN_CODE.getPayId());
        APIResponse<RespPreOrder> respAli=this.cashForScanTransfer(statement,details,PayWayEnum.PAY_WAY_ALIPAY_SCAN_CODE.getPayId());
        tbStatement.setWeixinErrMsg(respWeixin!=null&&respWeixin.isRet()==false?respWeixin.getErrmsg():null);
        tbStatement.setAliErrMsg(respAli!=null&&respAli.isRet()==false?respAli.getErrmsg():null);
        if (respWeixin!=null){
            tbStatement.setWeixinCodeUrl(respWeixin.getData()!=null?respWeixin.getData().getCodeUrl():null);
        }
        if (respAli!=null){
            tbStatement.setAliPayCodeUrl(respAli.getData()!=null?respAli.getData().getCodeUrl():null);
        }
        if (respWeixin!=null){
            tbStatement.setPayOrderNo(respWeixin.getData()!=null?respWeixin.getData().getOrderNo():null);
        }
        statement.setWeixinCodeUrl(tbStatement.getWeixinCodeUrl());
        statement.setAliPayCodeUrl(tbStatement.getAliPayCodeUrl());
        statementsMapper.updateByPrimaryKeySelective(tbStatement);

        StatementBaseInfo baseInfo = this.constructBaseInfo(statement);
        StatementInfo sInfo = new StatementInfo();
        sInfo.setBaseInfo(baseInfo);
        sInfo.setOrders(orders);
        return sInfo;
    }

    @Override
    public RespSaveTransferRemark saveTransferRemark(ReqSaveTransferRemark reqVo) {
        TbBizPlaceStatement oldStatement = statementsMapper.selectByPrimaryKey(reqVo.getId());
        if (oldStatement == null) {
            return new RespSaveTransferRemark("结算单不存在", null);
        }

        TbBizPlaceStatement voStatement = new TbBizPlaceStatement();
        voStatement.setTransferRemark(reqVo.getTransferRemark());

        TbBizPlaceStatementExample sExample = new TbBizPlaceStatementExample();
        TbBizPlaceStatementExample.Criteria sCriteria = sExample.createCriteria();
        sCriteria.andIdEqualTo(reqVo.getId());

        int ret = statementsMapper.updateByExampleSelective(voStatement, sExample);
        if (ret < 1) {
            return new RespSaveTransferRemark("更新结算单数据库失败!", null);
        }

        // 数据库中读取最新Baseinfo返回
        TbBizPlaceStatement newStatement = statementsMapper.selectByPrimaryKey(reqVo.getId());
        if (newStatement == null) {
            return new RespSaveTransferRemark("无法找到更新后的结算单!", null);
        }
        return new RespSaveTransferRemark(null, this.constructBaseInfo(newStatement));
    }

    @Override
    public RespTransferStatement transferStatement(ReqTransferStatement reqVo) {
        // 只有处于“申请结算”的结算单，商家才可以发起转账
        TbBizPlaceStatement oldStatement = statementsMapper.selectByPrimaryKey(reqVo.getId());
        if (oldStatement == null) {
            return new RespTransferStatement("结算单不存在", null);
        }

        StatementBaseInfo oldBaseInfo = this.constructBaseInfo(oldStatement);
        if (!oldBaseInfo.canTransfer()) {
            return new RespTransferStatement("结算单状态不对", null);
        }

        // 准备更新结算单状态
        TbBizPlaceStatement voStatement = new TbBizPlaceStatement();
        //voStatement.setTransferName(reqVo.getTransferName());
        voStatement.setTransferDate(reqVo.getTransferDate());
        voStatement.setTransferRemark(reqVo.getTransferRemark());
        voStatement.setStatementStatus((byte) 2); // 状态更新为已转账

        TbBizPlaceStatementExample sExample = new TbBizPlaceStatementExample();
        TbBizPlaceStatementExample.Criteria sCriteria = sExample.createCriteria();
        sCriteria.andIdEqualTo(reqVo.getId());

        int ret = statementsMapper.updateByExampleSelective(voStatement, sExample);
        if (ret < 1) {
            return new RespTransferStatement("更新结算单状态失败", null);
        }

        // 将结算单内所有订单的结算状态改为已转账（注意区分普通账单和会员充值）
        TbBizPlaceStatementDetailExample sdExample = new TbBizPlaceStatementDetailExample();
        TbBizPlaceStatementDetailExample.Criteria sdCriteria = sdExample.createCriteria();
        sdCriteria.andStatementIdEqualTo(reqVo.getId());

        List<String> normalNOs = new ArrayList<String>();
        List<String> debitNOs = new ArrayList<String>();  // 收入单订单号集合
        List<String> creditNOs = new ArrayList<String>(); // 支出单订单号集合

        List<String> memberNOS = new ArrayList<String>();
        List<TbBizPlaceStatementDetail> details = statementDetailMapper.selectByExample(sdExample);
        if (details != null) {
            for (TbBizPlaceStatementDetail detail : details) {
                if (detail.getOrderType() == 1) {
                    normalNOs.add(detail.getPlaceOrderId());

                    int flag = detail.getHandleMoney().compareTo(BigDecimal.ZERO);
                    if ( flag == 1 || flag == 0) {
                        debitNOs.add(detail.getPlaceOrderId());
                    } else {
                        creditNOs.add(detail.getPlaceOrderId());
                    }
                } else if (detail.getOrderType() == 2) {
                    memberNOS.add(detail.getPlaceOrderId());
                }
            }

            // 订单状态设置为已转账
            this.updateNormalOrderSettleStatus(null, debitNOs, (byte) 3, false);
            this.updateNormalOrderSettleStatus(null, creditNOs, (byte) 3, true);
            this.updateMemberOrderSettleStatus(null, memberNOS, (byte) 3);
        }

        // 数据库中读取最新Baseinfo返回
        TbBizPlaceStatement newStatement = statementsMapper.selectByPrimaryKey(reqVo.getId());
        if (newStatement == null) {
            return new RespTransferStatement("无法找到更新后的结算单!", null);
        }
        return new RespTransferStatement(null, this.constructBaseInfo(newStatement));
    }

    @Override
    public RespCreateStatement getMaxCashOrder(ReqCreateStatement reqVo) {


        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public APIResponse<RespPreOrder> cashForScanTransfer(TbBizPlaceStatement state,List<TbBizPlaceStatementDetail> detailList,Integer payWay) {
        List<ReqProductDetail> productDetailList=new ArrayList<>();
        APIRequest<ReqOrderSave> orderSaveApiRequest=new APIRequest<>();
        ReqOrderSave req=new ReqOrderSave();
        req.setOutTradeNo(state.getStatementId());
        req.setUid(-1);
        req.setOrderDescribe("自营场馆现金结算");
        req.setOrderAmount(state.getTotalAmount());
        req.setPayTimeOut(999999);
        req.setSourceSystemId(Constants.PLACE_SYSTEM_CODE);
        req.setSourceBusinessId(Constants.PLACE_CASH_SETTLE_CODE);
        List<ReqPayInfo> payInfos=new ArrayList<>();
        ReqPayInfo payInfo=new ReqPayInfo();
        payInfo.setPayId(payWay);
        payInfo.setAmount(state.getTotalAmount());
        payInfos.add(payInfo);
        req.setPayInfos(payInfos);
        //List<SettleOrder> list= this.getStatementList(reqVo.getStatementId());
        if (detailList!=null&&detailList.size()>0){
            for (TbBizPlaceStatementDetail detail:detailList){
                ReqProductDetail pro=new ReqProductDetail();
                pro.setProductId(detail.getPlaceOrderId());
                productDetailList.add(pro);
            }
        }
        req.setProductDetailList(productDetailList);
        req.setNotifyURL(cashForScanTransfer);
        orderSaveApiRequest.setData(req);
        //数据提交到订单系统
        APIResponse<RespPreOrder> result =orderPayService.submitOrder(orderSaveApiRequest);
        return result;
    }

    public List<SettleOrder>getStatementList(String statementId){
        List<SettleOrder> list=unSettleOrderMapper.getStatementDetailByStatementId(statementId);
        return list;
    }

    @Override
    public APIResponse cashForScanTransferCallback(OrderNotifyMsg vo) {
        if (vo==null){
           return APIResponse.returnFail("回调异常");
        }
        TbBizPlaceStatementExample sExample = new TbBizPlaceStatementExample();
        TbBizPlaceStatementExample.Criteria sCriteria = sExample.createCriteria();
        sCriteria.andStatementIdEqualTo(vo.getOutTradeNo());
        TbBizPlaceStatement state=new TbBizPlaceStatement();
        state.setStatementStatus((byte)2);
        state.setTransferDate(DateUtils.transferLongToDateFormat(vo.getPayTime()));
        statementsMapper.updateByExampleSelective(state,sExample);
        return APIResponse.returnSuccess("转账成功");
    }
}